package com.wfk.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wfk.constant.Constant;
import com.wfk.entity.Account;
import com.wfk.entity.BankDetails;
import com.wfk.entity.Customer;
import com.wfk.entity.SysCashDetails;
import com.wfk.entity.SysCashRule;
import com.wfk.enums.HandleType;
import com.wfk.enums.MerchantAccountTypeEnums;
import com.wfk.exception.ServiceException;
import com.wfk.mapper.SysCashDetailsMapper;
import com.wfk.service.IAccountService;
import com.wfk.service.IBankDetailsService;
import com.wfk.service.ICustomerService;
import com.wfk.service.ISysCashDetailsService;
import com.wfk.service.ISysCashRuleService;
import com.wfk.utils.BasePage;
import com.wfk.utils.FunctionUtils;
import com.wfk.utils.MD5Util;
import com.wfk.utils.ResponseData;
import com.wfk.utils.ValidateUtil;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;

/**
 * <p>
 * 提现申请记录表 服务实现类
 * </p>
 *
 * @since 2019-01-07
 */
@Service
public class SysCashDetailsServiceImpl extends ServiceImpl<SysCashDetailsMapper, SysCashDetails> implements ISysCashDetailsService {
	@Autowired
	private ISysCashRuleService cashRuleService ;
	@Autowired
	private IBankDetailsService bankDetailService ;
	@Autowired
	private SysCashDetailsMapper sysCashDetailsMapper;
	@Autowired
	private IAccountService accountService ;
	@Autowired
	private ICustomerService customerService;
	
	private Lock lock = new ReentrantLock() ;
	
	@Override
	public void getList(SysCashDetails cashDetails, BasePage<SysCashDetails> page) {
		QueryWrapper<SysCashDetails> ew = new QueryWrapper<SysCashDetails>();
		if(cashDetails.getTargetid() != null) {
			ew.eq("targetid", cashDetails.getTargetid()) ;
		}
		if(cashDetails.getStatus() != null) {
			ew.eq("status", cashDetails.getStatus()) ;
		}
		if(ValidateUtil.date(cashDetails.getStart())) {
			ew.ge("createtime", cashDetails.getStart());
		}
		if(ValidateUtil.date(cashDetails.getEnd())) {
			ew.le("createtime", cashDetails.getEnd());
		}
		if(page.isPage()) {
			super.page(page, ew) ;
		}else {
			List<SysCashDetails> data = super.list(ew);
			int total = super.count(ew);
			page.setRecords(data) ;
			page.setTotal(total) ;
		}
//		for(SysCashDetails details : page.getRecords()) {
//			Merchant merchant = merchantService.getById(details.getMerid());
//			BankDetails bankDetail = bankDetailService.getById(details.getBankid());
//			BankType bankType = bankTypeService.getById(bankDetail.getTypeid());
//			bankDetail.setBankType(bankType);
//			details.setMerchant(merchant);
//			details.setBankDetail(bankDetail);
//		}
	}

	@Override
	public ResponseData doCash(SysCashDetails cashDetail) {
		try {
			lock.lock();
			SysCashRule rule = cashRuleService.getOne(null);
			if(cashDetail.getBankid() == null) {
				return ResponseData.baseError("请选择一张银行卡") ;
			}else if(cashDetail.getCashmoney() == null) {
				return ResponseData.baseError("提现金额不能为空") ;
			}else if(ValidateUtil.objEmpty(cashDetail.getTargetid())) {
				return ResponseData.baseError("提现会员不存在");
			}else if(!ValidateUtil.empty(cashDetail.getPayword())) {
				return ResponseData.baseError("请输入提款密码");
			}
			Customer cus = this.customerService.getById(cashDetail.getTargetid());
			if(ValidateUtil.objEmpty(cus)) {
				return ResponseData.baseError("会员未注册");
			}
			String payw = MD5Util.md5Hex(cashDetail.getPayword());
			if(!ValidateUtil.equalTo(payw, cus.getPayword())) {
				return ResponseData.baseError("提款密码不正确");
			}
			if(rule.getMinval().compareTo(cashDetail.getCashmoney()) > 0 || cashDetail.getCashmoney().compareTo(rule.getMaxval()) > 0) {
				return ResponseData.baseError("提现金额必须在" + rule.getMinval() + "到" + rule.getMaxval() + "之间") ;
			}else if(ValidateUtil.objEmpty(rule)||ValidateUtil.isEquals(rule.getIsopen(),-1)) {
				return ResponseData.baseError("提现通道关闭");
			}
			Integer countCash = sysCashDetailsMapper.countCash(cashDetail.getTargetid(),DateUtil.tomorrow());
			if(countCash>=rule.getNum()) {
				return ResponseData.baseError("提现金额超过余额");
			}
			Account merchantAccount = accountService.get(cashDetail.getTargetid());
			if(merchantAccount.getMoney().compareTo(cashDetail.getCashmoney()) < 0) {
				return ResponseData.baseError("提现金额超过余额") ;
			}
			BankDetails bankDetails = bankDetailService.getById(cashDetail.getBankid());
			if(bankDetails == null) {
				return ResponseData.baseError("银行卡不存在") ;
			}else if(!ValidateUtil.isEquals(bankDetails.getTargetid(),cashDetail.getTargetid())) {
				return ResponseData.baseError("会员银行卡未通过") ;
			}
			String result = accountService.insertAccountDetail(cashDetail.getTargetid(),HandleType.cash.getId(), Constant.pay_out, cashDetail.getCashmoney(), "提现");
			if(StrUtil.isNotBlank(result)) {
				throw new ServiceException("提现失败") ;
			}
			
			BigDecimal scale = FunctionUtils.mul(cashDetail.getCashmoney(),rule.getScale() , 2) ;
			BigDecimal realmoney = FunctionUtils.sub(cashDetail.getCashmoney(), scale, 2) ;
			cashDetail.setRealmoney(realmoney);
			cashDetail.setBankcode(bankDetails.getBankcode());
			cashDetail.setBankname(bankDetails.getBankname());
			return super.save(cashDetail) ? ResponseData.ok() : ResponseData.baseError("提现失败") ;
		}catch(Exception e) {
			e.printStackTrace(); 
			throw e; 
		}finally {
			lock.unlock();
		}
	}

	@Override
	public ResponseData doCashPreper(Integer id, Integer status) {
		try {
			lock.lock();
			SysCashDetails cashDetail = super.getById(id);
			if(cashDetail.getStatus() != Constant.cash_ing) {
				return ResponseData.baseError("状态异常") ;
			}
			cashDetail.setEndtime(new Date());
			cashDetail.setStatus(status);
			boolean result = super.updateById(cashDetail);
			if(!result) {
				throw new ServiceException("处理失败") ;
			}
			if(status == Constant.cash_reject) {
				//提现驳回
				String moneyResult = accountService.insertAccountDetail(cashDetail.getTargetid(), 
						MerchantAccountTypeEnums.cash_reject.getId(), Constant.pay_in, cashDetail.getCashmoney(), "提现驳回") ;
				if(StrUtil.isNotBlank(moneyResult)) {
					throw new ServiceException("处理失败") ;
				}
			}
		}catch (Exception e) {
			e.printStackTrace();
			throw e;  
		}finally {
			lock.unlock();
		}
		
		return ResponseData.ok() ;
	}

	@Override
	public BigDecimal moneyCount(Integer status, Date time) {
		QueryWrapper<SysCashDetails> queryWrapper = new QueryWrapper<SysCashDetails>();
		queryWrapper.select("IFNULL(SUM(realmoney),0.00) AS moneyCount");
		if(time!=null) {
			queryWrapper.eq("DATE_FORMAT(createtime,'%m-%d-%Y')", "DATE_FORMAT("+time+",'%m-%d-%Y')");
		}
		if(status!=null) {
			queryWrapper.gt("status",status);
		}
		Map<String, Object> map = super.getMap(queryWrapper);
		return (BigDecimal) map.get("moneyCount");
	}
}
